package com.cn.ycy.config;


import com.cn.ycy.entity.result.R;
import com.cn.ycy.entity.result.ResultCode;
import com.cn.ycy.exception.RCException;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.lang3.StringUtils;
import org.springframework.context.annotation.Configuration;
import org.springframework.http.HttpStatus;
import org.springframework.web.bind.annotation.*;
import org.springframework.web.context.request.RequestContextHolder;
import org.springframework.web.context.request.ServletRequestAttributes;

import javax.servlet.http.HttpServletResponse;
import javax.validation.ConstraintViolation;
import javax.validation.ConstraintViolationException;
import java.util.Optional;

/**
 * 全局的的异常拦截器,若是500的异常fegin调用可能会失败
 *
 * @author qiss
 */
@Slf4j
@Configuration
@ControllerAdvice
@RestControllerAdvice
public class GlobalExceptionAutoConfiguration {

    private static final String MATCN_STR = ",\"resultMessage\":";


    /**
     * 全局异常.
     *
     * @param e the e
     * @return R
     */
    @ExceptionHandler(RCException.class)
    @ResponseStatus(HttpStatus.OK)
    @ResponseBody
    public R<?> rcexception(RCException e) {
        log.info("保存业务异常信息 ex={} ", e.getMessage(), e);
        Optional<ServletRequestAttributes> servletRequestAttributes = Optional.ofNullable((ServletRequestAttributes) RequestContextHolder.getRequestAttributes());
        Optional<HttpServletResponse> response = Optional.ofNullable(servletRequestAttributes.get().getResponse());
        Optional<ResultCode> resultCode = Optional.ofNullable(e.getResultCode());
        response.get().setHeader("resultCode", String.valueOf(resultCode.get().getCode()));
        return R.failure(e.getResultCode().getCode(), e.getMessage());
    }

//    /**
//     * 全局异常.
//     *
//     * @param e
//     *         the e
//     * @return R
//     */
//    @ExceptionHandler(FeignException.class)
//    @ResponseStatus(HttpStatus.OK)
//    @ResponseBody
//    public R<?> feignException(FeignException e) {
//        log.error("保存feign调用异常信息 ex=" + e.getMessage(), e);
//        //解message中的信息,"status 500 reading IUserService#searchDetailUserInfo(SearchDetailUserInfoRequest); content: {"code":500,"success":false,"data":{},"message":"测试发出!!!"}"
//        String retMsg = e.getMessage();
//        if (!StringUtils.isEmpty(retMsg) && retMsg.contains(MATCN_STR)) {
//            retMsg = retMsg.substring(retMsg.lastIndexOf(MATCN_STR) + 18, retMsg.length() - 2);
//        }
//        Optional<ServletRequestAttributes> servletRequestAttributes =  Optional.ofNullable((ServletRequestAttributes)RequestContextHolder.getRequestAttributes());
//        Optional<HttpServletResponse> response = Optional.ofNullable(servletRequestAttributes.get().getResponse());
//        response.get().setHeader("resultCode", String.valueOf(ResultCode.INTERNAL_SERVER_ERROR.getCode()));
//        return R.failure(retMsg);
//    }

    /**
     * 全局异常.
     *
     * @param e the e
     * @return R
     */
    @ExceptionHandler(ConstraintViolationException.class)
    @ResponseStatus(HttpStatus.OK)
    @ResponseBody
    public R<?> validateException(ConstraintViolationException e) {
        log.error("保存全局ConstraintViolationException异常信息 ex= {} ", e.getMessage(), e);
        StringBuilder sb = new StringBuilder();
        for (ConstraintViolation<?> cv : e.getConstraintViolations()) {
            sb.append(cv.getMessage()).append(",");
        }
        Optional<ServletRequestAttributes> servletRequestAttributes = Optional.ofNullable((ServletRequestAttributes) RequestContextHolder.getRequestAttributes());
        Optional<HttpServletResponse> response = Optional.ofNullable(servletRequestAttributes.get().getResponse());
        response.get().setHeader("resultCode", String.valueOf(ResultCode.PARAM_VALID_ERROR.getCode()));
        return R.failure(ResultCode.PARAM_VALID_ERROR, sb.deleteCharAt(sb.length() - 1).toString());
    }

    /**
     * 全局异常RuntimeException,注意因为返回得http是500feion调用会异常.
     *
     * @param e the e
     * @return R
     */
    @ExceptionHandler(RuntimeException.class)
    @ResponseStatus(HttpStatus.INTERNAL_SERVER_ERROR)
    @ResponseBody
    public R<?> exception(RuntimeException e) {
        log.error("保存全局RuntimeException异常信息 ex= {} ", e.getMessage(), e);
        Optional<ServletRequestAttributes> servletRequestAttributes = Optional.ofNullable((ServletRequestAttributes) RequestContextHolder.getRequestAttributes());
        Optional<HttpServletResponse> response = Optional.ofNullable(servletRequestAttributes.get().getResponse());
        response.get().setHeader("resultCode", String.valueOf(ResultCode.INTERNAL_SERVER_ERROR.getCode()));
        return R.failure(e.getMessage());
    }


    /**
     * 全局异常.
     *
     * @param e the e
     * @return R
     */
    @ExceptionHandler(Exception.class)
    @ResponseStatus(HttpStatus.INTERNAL_SERVER_ERROR)
    @ResponseBody
    public R<?> exception(Exception e) {
        log.error("保存全局Exception异常信息 ex = {} ", e.getMessage(), e);
        Optional<ServletRequestAttributes> servletRequestAttributes = Optional.ofNullable((ServletRequestAttributes) RequestContextHolder.getRequestAttributes());
        Optional<HttpServletResponse> response = Optional.ofNullable(servletRequestAttributes.get().getResponse());
        response.get().setHeader("resultCode", String.valueOf(ResultCode.INTERNAL_SERVER_ERROR.getCode()));
        return R.failure(e.getMessage());
    }

}
